#pragma once
#include <iostream>
#include <string>
#include <unordered_map>
#include <functional>
#include "tcpServer.hpp"
#include "httpProtocol.hpp"
using namespace tcpServerModule;
using http_handler_t = std::function<void(httpRuest &, httpResponse &)>;
class httpServer
{
private:
    std::unique_ptr<tcpServer> _tsvr;
    std::unordered_map<string, http_handler_t> _route; // 功能路由
public:
    httpServer(int port)
        : _tsvr(std::make_unique<tcpServer>(port))
    {
    }
    void Register(string funcName, http_handler_t func)
    {
        _route[funcName] = func;
    }
    void start()
    {
        _tsvr->inintServer([this](sockptr sockfd, InetAddr client)
                           { return this->handlerHttpRequest(sockfd, client); });
        _tsvr->loop();
    }
    bool safeCheck(const string &path)
    {
        auto iter = _route.find(path);
        return iter != _route.end();
    }
    bool handlerHttpRequest(sockptr sockfd, InetAddr client)
    {
        LOG(LogLevel::DEBUG) << "httpServer: get a new client: "
                             << sockfd->fd() << " addr info: " << client.Addr();
        std::string http_request;
        sockfd->Recv(&http_request); // * 在 http这里，我们不做保温完整性的处理
        httpRuest req;
        req.Deserialize(http_request);

        req.getContent(req.Path());
        cout << "用户想要: " << req.Uri() << endl;

        httpResponse resp;
        // * 请求的类型被分为2种， 1：请求的是静态资源 2. 携带参数携带参数需要我们进行交互设置，需要我们进行交互设置
        if (req.isHasArgs())
        {
            // 2. 携带参数，需要我们自己进行交互设置
            string service = req.Path();
            if (safeCheck(service))
                _route[req.Path()](req, resp); // login
            else 
                resp.Bulid(req);
        }
        else
        {
            resp.Bulid(req);
        }
        string resq_str;
        resp.serialize(&resq_str);
        sockfd->Send(resq_str);

        return true;

        // std::cout << http_request << std::endl; //* 面向字节流
        // // zdl:: 走到这一步本质上就是对httprequest 进行处理
        // // zdl:: 本质上就是对文本（协议） 进行处理
        // // * 1. 保证读取请求的完整性 --现在暂时不做
        // // * 2. 完整http反序列化， http response序列化
        // //  demo 1: 直接返回一个固定的内容
        // std::string status_line = "HTTP/1.1 200 OK" + sep + blankLine;
        // // 直接返回一个网页
        // std::string body = "<!DOCTYPE html>\
        //                    < html >\
        //                    <head>\
        //                    <title> Hello World</ title>\
        //                    </ head>\
        //                    <body>\
        //                    <h1> Hello,\
        //             World !</ h1>\
        //                 </ body> < / html > ";
        // std::string http_response = status_line + body;
        // sockfd->Send(http_response);

        return true;
    }
    ~httpServer()
    {
    }
};
